#!/usr/bin/env python
# -*- coding: utf-8 -*-


try:
	from scribus import *
except ImportError:
	print "This script can only be run as an extension script from Scribus"
	sys.exit(1)


def linearize(lst):
	i = iter(lst)
	result = i.next()
	
	try:
		while 1:
			result += i.next()
	except StopIteration:
		return result

def withFunction0(f, name=None):
	if name:
		return eval(f+"(\""+name+"\")")
	else:
		return eval(f+"()")

def withFunction1(f, param, name=None):
	if name:
		return eval(f+"(\""+str(param)+"\",\""+name+"\")")
	else:
		return eval(f+"(\""+str(param)+"\")")


##########################################
############ ScribusDocument #############
##########################################

class ScribusDocument:
	def sHaveDoc(self):
		return haveDoc()
	
	def sNewDoc(self, *args):
		return newDoc(args[0], args[1], args[2], args[3], args[4], args[5], args[6])

	def sCloseDoc(self):
		return closeDoc()
	
	def sSaveDoc(self):
		return saveDoc()
	
	def sSaveDocAs(self, name):
		return saveDocAs(name)
	
	def sOpenDoc(self, name):
		return openDoc(name)
	
	def sDocChanged(self, bool):
		return docChanged(bool)
##########################################
############## ScribusPage ###############
##########################################

class ScribusPage:
	def sNewPage(self, where):
		return newPage(where)
	
	def sGotoPage(self, nr):
		return gotoPage(nr)
	
	def sPageCount(self):
		return pageCount()
	
	def sRedrawAll(self):
		return redrawAll()
	
	def sGetPageItems(self):
		return getPageItems()

###########################################
############## ScribusShape ###############
###########################################

class ScribusShape:
	#def __del__(self):
	def sGetPosition(self, name=None):
		return withFunction0("getPosition", name)
	
	def sSetPosition(self, pos, name=None):
		#return withFunction1("setPosition", pos, name)
		if name:
			return moveObjectAbs(pos[0], pos[1], name)
		else:
			return moveObjectAbs(pos[0], pos[1])
		
	def sGetSize(self, name=None):
		return withFunction0("getSize", name)
		
	def sSetSize(self, siz, name=None):
		#return withFunction1("setSize", siz, name)
		pos = self.sGetPosition(name)
		size = map(lambda x, y: x+y, siz, pos)
		
		if name:
			return sizeObject(size[0], size[1], name)
		else:
			return sizeObject(size[0], size[1])
	
	def sGetSelectedObject(self):
		return getSelectedObject()
	
	def sObjectExists(self, name=None):
		return withFunction0("objectExists", name)
	
	#def sCreateText(self, x, y, width, height, name=None):
		#if name:
			#return createText(x, y, width, height, name)
		#else:
			#return createText(x, y, width, height)
		
	def sSelectObject(self, name):
		return selectObject(name)
	
	def sGetCornerRadius(self, name=None):
		return withFunction0("getCornerRadius", name)
	
	def sGetFillColor(self, name=None):
		return withFunction0("getFillColor", name)
	
	def sGetFillBlendMode(self, name=None):
		return None #withFunction0("getFillBlendmode", name)
	
	def sGetFillShade(self, name=None):
		return withFunction0("getFillShade", name)

	def sGetFillTransparency(self, name=None):
		return None #withFunction0("getFillTransparency", name)
	
	def sGetLineColor(self, name):
		return withFunction0("getLineColor", name)
	
	def sGetLineStyle(self, name):
		return withFunction0("getLineStyle", name)
	
	def sGetLineWidth(self, name=None):
		return withFunction0("getLineWidth", name)
	
	def sGetLineTransparency(self, name=None):
		return None #withFunction0("getLineTransparency", name)
	
	def sGetRotation(self, name=None):
		return withFunction0("getRotation", name)
	
	def sSetCornerRadius(self, radius, name=None):
		if name:
			return setCornerRadius(radius, name)
		else:
			return setCornerRadius(radius)
		
	def sSetFillColor(self, color, name=None):
		if name:
			return setFillColor(color, name)
		else:
			return setFillColor(color)
	
	def sSetFillBlendMode(self, blendmode, name=None):
		if name:
			return None #setFillBlendMode(blendmode, name)
		else:
			return None #setFillBlendMode(blendmode)
		
	def sSetFillShade(self, shade, name=None):
		if name:
			return setFillShade(shade, name)
		else:
			return setFillShade(shade)
		
	def sSetFillTransparency(self, transparency, name=None):
		if name:
			return None #setFillTransparency(transparency, name)
		else:
			return None #setFillTransparency(transparency)
		
	def sSetLineColor(self, color, name=None):
		#return withFunction1("setLineColor", color, name)
		if name:
			return setLineColor(color, name)
		else:
			return setLineColor(color)
	
	def sSetLineStyle(self, style, name=None):
		if name:
			return setLineStyle(style, name)
		else:
			return setLineStyle(style)
		
	def sSetLineWidth(self, width, name=None):
		if name:
			return setLineWidth(width, name)
		else:
			return setLineWidth(width)
		
	def sSetLineTransparency(self, transparency, name=None):
		if name:
			return None #setLineTransparency(transparency, name)
		else:
			return None #setLineTransparency(transparency)
		
	def sSetRotation(self, rot, name=None):
		if name:
			return rotateObjectAbs(rot, name)
		else:
			return rotateObjectAbs(rot)
		
	def getShapeProperties(self, name=None):
		if not name:
			name = self.sGetSelectedObject()
			
		shape_properties = {}
		
		shape_properties["position"] = self.sGetPosition(name)
		shape_properties["size"] = self.sGetSize(name)
		shape_properties["corner_radius"] = self.sGetCornerRadius(name)
		shape_properties["fill_color"] = self.sGetFillColor(name)
		shape_properties["fill_blendmode"] = self.sGetFillBlendMode(name)
		shape_properties["fill_shade"] = self.sGetFillShade(name)
		shape_properties["fill_transparency"] = self.sGetFillTransparency(name)
		shape_properties["line_spacing"] = self.sGetLineSpacing(name)
		shape_properties["line_color"] = self.sGetLineColor(name)
		shape_properties["line_style"] = self.sGetLineStyle(name)
		shape_properties["line_width"] = self.sGetLineWidth(name)
		shape_properties["line_transparency"] = self.sGetLineTransparency(name)
		shape_properties["rotation"] = self.sGetRotation(name)
		
		return shape_properties
			
	
	def setShapeProperties(self, args, name=None):
		if not name:
			nam = self.sGetSelectedObject()
			
		if args.has_key("position"):
			self.sSetPosition(args["position"], name)
			
		if args.has_key("size"):
			self.sSetSize(args["size"], name)
			
		if args.has_key("corner_radius"):
			self.sSetCornerRadius(args["corner_radius"], name)
			
		if args.has_key("fill_color"):
			self.sSetFillColor(args["fill_color"], name)
			
		if args.has_key("fill_blendmode"):
			self.sSetFillBlendMode(args["fill_blendmode"], name)
			
		if args.has_key("fill_shade"):
			self.sSetFillShade(args["fill_shade"], name)
			
		if args.has_key("fill_transparency"):
			self.sSetFillTransparency(args["fill_transparency"], name)
			
		if args.has_key("line_spacing"):
			self.sSetLineSpacing(args["line_spacing"], name)
			
		if args.has_key("line_color"):
			self.sSetLineColor(args["line_color"], name)
			
		if args.has_key("line_style"):
			self.sSetLineStyle(args["line_style"], name)
			
		if args.has_key("line_width"):
			self.sSetLineWidth(args["line_width"], name)
			
		if args.has_key("line_transparency"):
			self.sSetLineTransparency(args["line_transparency"], name)
			
		if args.has_key("rotation"):
			self.sSetRotation(args["rotation"], name)
			
	def sSetProperties(self, args, name=None):
		pass #setShapeProperties(args, name)

	def getAllObjectsDictionary(self):
		"""
		Returns dictionary of all frames in the document
		Key is name, value is type.
		For example {'Text1' : 4} - name 'Text1' is a Text Frame.
		"""
		all_frames = self.sGetPageItems()
		all_frames_dictionary = {}
		
		for frame in all_frames:
			all_frames_dictionary[frame[0]] = frame[1]
			
		return all_frames_dictionary

	def whatIsTheObject(self, current_object = None):
		"""
		Returns type of the Text Frame named current_object. 
		If is none, returns the type of the selected object.
		"""
		if not current_object:
			current_object = self.sGetSelectedObject()
		
		try:
			return self.getAllObjectsDictionary()[current_object]
		except:
			return

	def sCopy(self, name):
		pass
	

	

##########################################
############## ScribusText ###############
##########################################

class ScribusText(ScribusShape):
	#def __init__(self, x, y, width, height, name=None):
		#self.name = name
		#self.x = x
		#self.y = y
		#self.width = width
		#self.height = height
		
	#def sShow(self):
		#if name:
			#createText(self.x, self.y, self.width, self.height, self.name)
		#else:
			#self.name = createText(self.x, self.y, self.width, self.height)

	def selectAllText(self, name):
		text = self.sGetText(name)
		stop = len(text)
		selectText(0, stop, name)
		
	def sCreateText(self, x, y, width, height, name=None):
		if name:
			return createText(x, y, width, height, name)
		else:
			return createText(x, y, width, height)
		
		
	def sInsertText(self, text, pos, name=None):
		if name:
			return insertText(text, pos, name)
		else:
			return insertText(text, pos)
		
	def sGetText(self, name=None):
		return withFunction0("getText", name)
	
	def sGetAllText(self, name=None):
		return withFunction0("getAllText", name)
		
	def sGetColumns(self, name=None):
		return withFunction0("getColumns", name)
		
	def sGetFont(self, name=None):
		self.selectAllText(name)
		
		return withFunction0("getFont", name)
		
	def sGetFontSize(self, name=None):
		self.selectAllText(name)
		
		return withFunction0("getFontSize", name)
		
	def sGetLineSpacing(self, name=None):
		return withFunction0("getLineSpacing", name)
		
	def sGetTextColor(self, name=None):
		self.selectAllText(name)
		
		try:
			return withFunction0("getTextColor", name)
		except:
			return "Black"
		
	def sSetColumns(self, nr, name=None):
		#return withFunction1("setColumns", nr, name)
		if name:
			return setColumns(nr, name)
		else:
			return setColumns(nr)
		
	def sSetFont(self, font, name=None):
		return withFunction1("setFont", font, name)
	
	def sSetFontSize(self, nr, name=None):
		#return withFunction1("setFontSize", name)
		if name:
			return setFontSize(nr, name)
		else:
			return setFontSize(nr)
	
	def sSetLineSpacing(self, nr, name=None):
		#return withFunction1("setLineSpacing", nr, name)
		if name:
			return setLineSpacing(nr, name)
		else:
			return setLineSpacing(nr)
	
	def sSetTextColor(self, color, name=None):
		return withFunction1("setTextColor", color, name)
	
	def sDeleteText(self, name=None):
		return withFunction0("deleteText", name)
	
	def getTextProperties(self, name = None):
		if not name:
			if self.whatIsTheObject() == 4:
				name = self.sGetSelectedObject()
			else:
				print "getTextProperties(): no Text Frame selected."
				return 0
			
		text_properties = {}
		
		text_properties["columns"] = self.sGetColumns(name)
		text_properties["font"] = self.sGetFont(name)
		text_properties["font_size"] = self.sGetFontSize(name)
		text_properties["line_spacing"] = self.sGetLineSpacing(name)
		text_properties["text_color"] = self.sGetTextColor(name)
		text_properties["text"] = self.sGetText(name)

		shape_properties = self.getShapeProperties(name)
		
		text_properties.update(shape_properties)
		
		return text_properties
			
	def setTextProperties(self, args, name=None):
		if not name:
			name = self.sGetSelectedObject()
			
		if args.has_key("columns"):
			self.sSetColumns(args["columns"], name)
			
		if args.has_key("font"):
			self.sSetFont(args["font"], name)
			
		if args.has_key("font_size"):
			self.sSetFontSize(args["font_size"], name)
			
		if args.has_key("line_spacing"):
			self.sSetLineSpacing(args["line_spacing"], name)
			
		if args.has_key("text_color"):
			self.sSetTextColor(args["text_color"], name)
			
		if args.has_key("text"):
			self.sInsertText(args["text"], -1, name)
			
		self.setShapeProperties(args, name)
		
	def sSetProperties(self, args, name=None):
		self.setTextProperties(args, name)
	
	
#####################################
############## Shapes ###############
#####################################
	
class BezierLine(ScribusShape):
	def __init__(self, lst, name=None):
		self.name = name
		self.lst = lst
		
	def sShow(self):
		if self.name:
			createBezierLine(self.lst, self.name)
		else:
			self.name = createBezierLine(self.lst)
	
class Ellipse(ScribusShape):
	def __init__(self, x, y, width, height, name=None):
		self.name = name
		self.x = x
		self.y = y
		self.width = width
		self.height = height
		
	def sShow(self):
		if self.name:
			createEllipse(self.x, self.y, self.width, self.height, self.name)
		else:
			self.name = createEllipse(self.x, self.y, self.width, self.height)
			
class Image(ScribusShape):
	def __init__(self, x, y, width, height, name=None):
		self.name = name
		self.x = s
		self.y = y
		self.width = width
		self.height = height
		
	def sShow(self):
		if self.name:
			createImage(self.x, self.y, self.width, self.height, self.name)
		else:
			self.name = createImage(self.x, self.y, self.width, self.height)
			
class Line(ScribusShape):
	def __init__(self, x1, y1, x2, y2, name=None):
		self.name = name
		self.x1, self.x2 = x1, x2
		self.y1, self.y2 = y1, y2
		
	def sShow(self):
		if self.name:
			createLine(self.x1, self.y1, self.x2, self.y2, self.name)
		else:
			self.name = createLine(self.x1, self.y1, self.x2, self.y2)
			
class PathText(ScribusShape):
	def __init__(self, x, y, textbox, beziercurve, name=None):
		self.name = name
		self.x = x
		self.y = y
		self.textbox = textbox
		self.beziercurve = beziercurve
		
	def sShow(self):
		if self.name:
			createPathText(self.x, self.y, self.textbox, self.beziercurve, self.name)
		else:
			self.name = createPathText(self.x, self.y, self.textbox, self.beziercurve)
			
class PolyLine(ScribusShape):
	def __init__(self, lst, name=None):
		self.name = name
		self.lst = lst
		
	def sShow(self):
		if self.name:
			createPolyLine(self.lst, self.name)
		else:
			self.name = createPolyLine(self.lst)
			
class Polygon(ScribusShape):
	def __init__(self, lst, name=None):
		self.name = name
		self.lst = lst
		
	def sShow(self):
		if self.name:
			createPolygon(self.lst, self.name)
		else:
			self.name = createPolygon(self.lst)
			
class Rect(ScribusShape):
	def __init__(self, x, y, width, height, name=None):
		self.name = name
		self.x = x
		self.y = y
		self.width = width
		self.height = height
		
	def sShow(self):
		if self.name:
			createRect(self.x, self.y, self.width, self.height, self.name)
		else:
			self.name = createRect(self.x, self.y, self.width, self.height)
			
				
			
###########################################
############# ScribusHandler ##############
###########################################

class ScribusHandler(ScribusText, ScribusPage, ScribusDocument):
			
	def parseTags(self, text, names):
		"""
		Parsing the text, returns list of stripped tags + list of parsing text without tags.
		"""
		splitted = text.split('<')
		tags = []
		new = []
		for item in splitted:
			tmp = item.split('>')
			if len(item) > 1:
				if tmp[0] in names:
					tags.append(tmp[0])
					tmp[0] = "#MailMergeTag#"
			new.append(tmp)
				
		return tags, linearize(new)
	
	def getObjectsPreferences(self, list_with_objects, text=None):
		"""
		Takes a list with objects names.
		Returns dictionary. Key is name of object,
		value is dictionary of preferecnes.
		"""
		properties = {}
		
		for object in list_with_objects:
			if text:
				properties[object] = self.getTextProperties(object)
			else:
				properties[object] = self.getShapeProperties(object)
		
		return properties

	
	def createObject(self, object_type):
		"""
		Takes integer - type of object.
		Create text or image frame or returns None.
		Version 1.2.x can set text frame and image only.
		"""
		if object_type == 4:
			return self.sCreateText(0,0,0,0)
		elif object_type == 2:
			return Image(0,0,0,0)
		else:
			return None
	
	def copyObjects(self, list_with_objects=None, dictionary_with_preferences=None):
		"""
		Takes a list with objects names or 
		Makes objects copies.
		"""
		print list_with_objects
		print dictionary_with_preferences
		
		if list_with_objects:
			dictionary_with_preferences = self.getObjectsPreferences(list_with_objects)
			
		if dictionary_with_preferences:
			for obj in dictionary_with_preferences.keys():
				o = self.createObject(4)
				self.sSetProperties(dictionary_with_preferences[obj], str(o))

	
	def copyTextFrame(self, new_name, properties=None, spec=None):
		if not spec:
			spec = self.sGetSelectedObject()
			
		if not properties:
			properties = self.getTextProperties(spec)
			
		x, y = properties["position"][0], properties["position"][1]
		
		self.sCreateText(x, y, 0, 0, new_name) # because sizeObject() in 1.2.x vesions is not correct
		self.setTextProperties(properties, new_name)
		
	def onlyTxtFrame(self):
		all_frames = self.sGetPageItems()
		txt = []
		for frame in all_frames:
			if frame[1] == 4:
				txt.append(frame[0])
		return txt